package org.zhq.core;

import org.zhq.util.CloseUtils;

import java.io.Closeable;

/**
 * 公共的数据封装
 * 提供了类型以及基本的长度定义
 *
 * @author zhengquan
 * @date 2019/2/1
 */
public abstract class Packet<Stream extends Closeable> implements Closeable {

    //BYTE
    public static final byte TYPE_MEMORY_BYTES = 1;

    //STRING
    public static final byte TYPE_MEMORY_STRING = 2;

    //FILE
    public static final byte TYPE_STREAM_FILE = 3;

    //长连接
    public static final byte TYPE_STREAM_DIRECT = 4;

    //5个字节满载的long类型
    public static final long MAX_PACKET_SIZE = (((0xFFL) << 32) |
            ((0xFFL) << 24) | ((0xFFL) << 16) | ((0xFFL) << 8) | ((0xFFL)));

    protected long length;

    private Stream steam;

    @Override
    public final void close() {
        if (steam != null) {
            closeStream(steam);
            steam = null;
        }
    }

    @Override
    public String toString() {
        return "Packet{" +
                "type=" + type() +
                ", length=" + length() +
                '}';
    }

    public long length() {
        return length;
    }

    /**
     * 创建流操作,应当将当前需要传输的数据转化为流
     *
     * @return
     */
    protected abstract Stream createStream();

    /**
     * 类型,直接通过方法得到
     * <p>
     * {@link #TYPE_MEMORY_BYTES}
     * {@link #TYPE_MEMORY_STRING}
     * {@link #TYPE_STREAM_FILE}
     * {@link #TYPE_STREAM_DIRECT}
     *
     * @return
     */
    public abstract byte type();

    /**
     * 关闭流
     *
     * @param steam
     */
    protected void closeStream(Stream steam) {
        CloseUtils.close(steam);
    }

    public final Stream open() {
        if (steam == null) {
            steam = createStream();
        }
        return steam;
    }

    /**
     * 头部额外信息,用于携带额外的校验信息等
     *
     * @return byte 数组,最大255长度
     */
    public byte[] headerInfo() {
        return null;
    }


}
